
import { RoomStatusEnum } from "../enum/room_enum";
import { Config } from "../types/config_type";
import { UserInfo } from "../types/user_type";
import { RoomPersonStatusType, LogoutRoomType, LoginRoomType } from "../types/room_type";
import deviceDetectionUtils from "../utils/device_detection";
import throwError from "../utils/throwError";
import VideoMediaStram from "./video_media_stram";
import CameraEnum from "../enum/camera_enum";
import Application from "../application/application";



/**
 * 房间管理
 */
class SFRTCRoom {
  /**
   * 是否已经进房
   */
  private _isLoginRoom : boolean = false;
  /**
   * 监听器列表
   */
  private readonly _listenMap = {
    join: Array<(result: RoomPersonStatusType) => void>(),
    exit: Array<(result: RoomPersonStatusType) => void>()
  };
  private _userInfo: UserInfo = {}
  private _config: Config | null = null;
  private _isDeviceSupport: boolean | null = null; 
  private _mediaStram: VideoMediaStram | null = null;

  
  constructor (config: Config) {
    this._config = config

    this._mediaStram = new VideoMediaStram(this._config)
  }


  /**
   * 获取当前进房状态
   */
  get getLoginRoomStatus () : boolean {
    return this._isLoginRoom;
  }

  /**
   * 加入房间
   * @param options 配置参数
   */
  async loginRoom (options: LoginRoomType) : Promise<boolean> {

    Application.setUserInfo({
      userId: options.userId,
      userName: options.roomName
    })
    Application.setRoomName(options.roomName)

    // TODO
    this._notice({
      type: RoomStatusEnum.join,
      message: 'login room success!',
      detail: {
        userId: this._userInfo.userId
      }
    })
    return false
  }

  /**
   * 离开房间
   * @param options 配置参数
   */
  async logoutRoom (options: LogoutRoomType) : Promise<boolean> {

    this.stopPublish()

    // TODO
    this._notice({
      type: RoomStatusEnum.exit,
      message: 'logout room success!',
      detail: {
        userId: this._userInfo.userId
      }
    })
    return false
  }

  /**
   * 注册 房间管理监听事件
   * @param evenName 注册的事件名
   */
  on (evenName: RoomStatusEnum, listenCallback: (result: RoomPersonStatusType) => void) :void {
    this._listenMap[evenName].push(listenCallback)
  }
  /**
   * 移除 房间管理监听事件
   */
  off (evenName: RoomStatusEnum, listenCallback: Function) :void {
    this._listenMap[evenName] = this._listenMap[evenName].filter(item => item != listenCallback)
  }
  /**
   * 通知
   */
  _notice (noticeContent: RoomPersonStatusType) {
    const list = this._listenMap[noticeContent.type]
    
    list.forEach((fn: (result: RoomPersonStatusType) => void) => {
      fn(noticeContent)
    })
  }

  /**
   * 本地预览音视频流
   * @param mountDom 挂载节点，能够被[querySelector] 获取到的节点
   */
  async localStartPreview (mountDom: string) : Promise<UserInfo> {
    if (this._isDeviceSupport == null) {
      this._isDeviceSupport = await deviceDetectionUtils()
    }

    if (!this._isDeviceSupport) {
      await throwError('The current device does not support')
      return {}
    }

    try {
      const result = await this._mediaStram?.createTempMediaStream(mountDom)

      // TODO
      return {}
    } catch (error) {
      throwError(error)
      return {}
    }
  }
  /**
  * 结束本地预览音视频流
  */
  localStopPreview () {}
  /**
  * 切换相机
  */
  async switchCamera (type: CameraEnum) :Promise<void> {
    this._mediaStram?.switchCamera(type)
  }
  /**
  * 设置麦克风采集音频状态
  * @param status true 为采集；false 为不采集
  */
  async setMicroState (status: boolean) :Promise<void> {
    this._mediaStram?.setMicroState(status)
  }

  async publish () :Promise<void> {
    this._mediaStram?.publish()
  }

  async stopPublish () :Promise<void> {
    this._mediaStram?.stopPublish()
  }


  
}


export default SFRTCRoom